package com.tanhua.dubbo.huanxin.service;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.tanhua.dubbo.huanxin.config.HuanXinConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class TokenService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String REDIS_KEY = "HX_TOKEN";

    @Autowired
    private HuanXinConfig huanXinConfig;

    /**
     * 获取token，首选从redis中命中，如果没有命中需要调用环信API获取token
     *
     * @return
     */
    public String getToken() {
        String token = this.redisTemplate.opsForValue().get(REDIS_KEY);
        if (StrUtil.isNotEmpty(token)) {
            return token;
        }
        //token已经失效
        return refreshToken();
    }

    /**
     * 从环信的API获取token，并且存储到redis
     *
     * @return
     */
    public String refreshToken() {
        //请求地址
        String url = StrUtil.format("{}{}/{}/token",
                this.huanXinConfig.getUrl(),
                this.huanXinConfig.getOrgName(),
                this.huanXinConfig.getAppName());

        //请求参数
        Map<Object, Object> requestParamMap = MapUtil.builder()
                .put("grant_type", "client_credentials")
                .put("client_id", this.huanXinConfig.getClientId())
                .put("client_secret", this.huanXinConfig.getClientSecret()).build();


        HttpResponse httpResponse = HttpRequest.post(url)
                .header(Header.CONTENT_TYPE, "application/json") //请求头
                .body(JSONUtil.toJsonStr(requestParamMap)) // 请求体
                .timeout(20000)//超时，毫秒
                .execute();//执行请求

        if (!httpResponse.isOk()) {
            //获取token失败
            return null;
        }

        String body = httpResponse.body(); //json字符串
        JSONObject jsonObject = JSONUtil.parseObj(body);//解析json

        String token = jsonObject.getStr("access_token");
        Long expiresIn = jsonObject.getLong("expires_in") - 3600; //有效期时间，单位：秒

        //将token存储到redis中
        this.redisTemplate.opsForValue().set(REDIS_KEY, token, expiresIn, TimeUnit.SECONDS);

        return token;
    }

}
